﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


namespace MainScene
{
    public enum TypeNode
    {
        Scene=0,
        Action=1
    }

    /// <summary>
    /// gflt;
    /// </summary>
    [Serializable]
    public class ClassCase
    {
        /// <summary>
        /// название вершины
        /// </summary>
        private string _name;
        private List<ClassCase> _a_part_of;
        private List<string> _secName;//is_a некто
        private bool _isDestroyed;
        //start Ирина (22.03.11)
        private float _x_d2;
        private float _y_d2;
        //end Ирина (22.03.11)
        public bool IsDestroyed
        {
            get { return _isDestroyed; }
            set { _isDestroyed = value; }
        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public List<ClassCase> A_part_of
        {
            get { return _a_part_of; }
            set { _a_part_of = value; }
        }
        public List<string> SecName
        {
            get { return _secName; }
            set { _secName = value; }
        }
        //start Ирина (22.03.11)
        public float X_d2
        {
            get { return _x_d2; }
            set { _x_d2 = value; }
        }
        public float Y_d2
        {
            get { return _y_d2; }
            set { _y_d2 = value; }
        }
        //end Ирина (22.03.11)
    }

    /// <summary>
    /// падежная рамка
    /// </summary>
    [Serializable]
    public class ClassCaseFrame
    {
        private ClassCase _agent;
        private ClassCase _recipient;
        private ClassCase _lokotiv;
        private ClassCase _time;
        private ClassCase _toDo;
        private ClassCase _obj;

        public ClassCaseFrame()
        {
        }

        public ClassCase Obj
        {
            get { return _obj; }
            set { _obj = value; }
        }
        public ClassCase Agent
        {
            get { return _agent; }
            set { _agent = value; }
        }
        public ClassCase Recipient
        {
            get { return _recipient; }
            set { _recipient = value; }
        }
        public ClassCase Lokotiv
        {
            get { return _lokotiv; }
            set { _lokotiv = value; }
        }
        public ClassCase Time
        {
            get { return _time; }
            set { _time = value; }
        }
        public ClassCase ToDo
        {
            get { return _toDo; }
            set { _toDo = value; }
        }

    }


    /// <summary>
    /// Вершина семантической сети
    /// </summary>
    [Serializable]
    public class ClassNode
    {
        private string _name;//название сцены
        private TypeNode _typeN;//тип: действие или сцена
        private List<ClassNode> _parent;//Список вершин, из которых возможен переход в данную
        private List<ClassNode> _lstNodes;//Список вершин, на которые ссылается сцена
        private ClassCaseFrame _caseFrame;//Падежная рамка вершины-действия
        private bool _isRepeated;//Повторяемая ли эта сцена
        private int _numOfCurrentBrowse = 0;//Который раз попали в эту вершину
        //29.03.11. Ульяна <!--
        public int NumOfCurrentBrowse { set; get; }//Который раз попали в эту вершину
        public ClassNode ArriveFrom { set; get; }//откуда пришли в эту вершину
        public ClassNode LastParent { set; get; }//откуда спустились в вершину
        public int MaxBrowse { set; get; }//Сколько раз должны обойти
        //29.03.11. Ульяна -->
        //start Ирина (22.03.11)
        private float _x;//координата по X
        private float _y;//координата по Y
        private float _x_d2;//координата по Х на diagram2
        private float _y_d2;//координата по У на diagram2
        //end Ирина (22.03.11)
        public ClassNode()
        {
        }

        public ClassNode(TypeNode type)
        {
            _typeN=type;
            _isRepeated = false;
            _parent=new List<ClassNode>();
            _lstNodes = new List<ClassNode>();
        }
        
        /// <summary>
        /// Имя сцены
        /// </summary>
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        /// <summary>
        /// Повторяемая ли эта сцена
        /// </summary>
        public bool IsRepeated
        {
            get { return _isRepeated; }
            set { _isRepeated = value; }
        }

        /// <summary>
        /// Падежная рамка для действия
        /// </summary>
        public ClassCaseFrame CaseFrame
        {
            get { return _caseFrame; }
            set { _caseFrame = value; }
        }

        /// <summary>
        /// Тип этой вершины
        /// </summary>
        public TypeNode TypeN
        {
            get { return _typeN; }
            set { _typeN = value; }
        }

        /// <summary>
        /// Список вершин, на которые ссылается текущая сцена
        /// </summary>
        public List<ClassNode> LstNodes
        {
            get { return _lstNodes; }
            set { _lstNodes = value; }
        }

        /// <summary>
        /// Список вершин, которые ссылаются на текущую сцену
        /// </summary>
        public List<ClassNode> LstParent
        {
            get { return _parent; }
            set { _parent = value; }
        }
        //start Ирина (22.03.11)

        /// <summary>
        /// Координата вершины по Х
        /// </summary>
        public float X
        {
            get { return _x; }
            set { _x = value; }
        }
        /// <summary>
        /// Координата вершины по У
        /// </summary>
        public float Y
        {
            get { return _y; }
            set { _y = value; }
        }
        /// <summary>
        /// Координата вершина по Х на диаграмме просмотра
        /// </summary>
        public float X_d2
        {
            get { return _x_d2; }
            set { _x_d2 = value; }
        }
        /// <summary>
        /// Координата вершины по У на диаграмме просмотра
        /// </summary>
        public float Y_d2
        {
            get { return _y_d2; }
            set { _y_d2 = value; }
        }
        //end Ирина (22.03.11)

        /// <summary>
        /// Получить ссылку на вершину по ее имени
        /// </summary>
        /// <param name="curname">имя сцены, которую надо найти</param>
        /// <returns></returns>
        public ClassNode GetNodeByName(string curname)
        {
            if (curname.Trim().ToUpper() == _name.Trim().ToUpper())
                return this;
            else
            {
                ClassNode SceneN;
                foreach (ClassNode node in _lstNodes)
                {
                    if (node.TypeN == TypeNode.Scene)
                    {
                        if (node.Name.Trim().ToUpper() == curname.Trim().ToUpper())
                            return node;
                        else SceneN = node.GetNodeByName(curname);
                        if (SceneN != null)
                            return SceneN;
                    }
                }
                return null;
            }
        }

        /*/// <summary>
        /// получить следующую для просмотра вершину
        /// </summary>
        /// <param name="ArcNum">номер дуги</param>
        /// <param name="curname">имя сцены, из котороый выходит дуга</param>
        /// <returns></returns>
        public ClassNode GetNextNode(int ArcNum,string curname)
        {
            ClassNode CurNode = GetNodeByName(curname);
            if (ArcNum >= CurNode.LstNodes.Count)
                return null;
            else return CurNode.LstNodes[ArcNum];
        }*/

        /// <summary>
        /// Сформировать текст по падежной рамке
        /// </summary>
        /// <returns></returns>
        public string GetText(Taxonomia tx,int k)
        {
            if (this._typeN == TypeNode.Scene)
                return "";
            else
            {
                string str = "";
                if (_caseFrame.Agent != null)
                {
                    if (_caseFrame.Agent.Name!="")
                        if (tx.GetRole(_caseFrame.Agent.Name)==null)
                            str += "<неопределенный персонаж>" + " ";
                        else str += tx.GetRole(_caseFrame.Agent.Name).Heroes[k] + " ";
                    else str += _caseFrame.Agent.Name + " ";
                }
                if (_caseFrame.ToDo != null)
                    str += _caseFrame.ToDo.Name + " ";
                if (_caseFrame.Recipient != null)
                {
                    if (_caseFrame.Recipient.Name != "")
                        if (tx.GetRole(_caseFrame.Recipient.Name) == null)
                            str += "<неопределенный персонаж>" + " ";
                        else str += tx.GetRole(_caseFrame.Recipient.Name).Heroes[k] + " ";
                    else str += _caseFrame.Recipient.Name + " ";
                }
                if (_caseFrame.Obj != null)
                    str += _caseFrame.Obj.Name + " ";
                if (_caseFrame.Lokotiv != null)
                    str += _caseFrame.Lokotiv.Name + " ";
                if (_caseFrame.Time != null)
                    str += _caseFrame.Time.Name + ". ";
                return  str;
            }
        }
    }

    [Serializable]
    public class Role
    {
        private string name;
        List<string> _heroes = new List<string>();
        public List<string> Heroes
        {
            set { _heroes = value; }
            get { return _heroes; }
        }
        public string Name
        {
            set { name = value; }
            get { return name; }
        }
        public Role()
        {
        }
        public Role(string n)
        {
            name = n;
        }
        public bool IsExistHero(string name)
        {
            foreach (string h in Heroes)
            {
                if (h.Trim().ToUpper() == name.Trim().ToUpper())
                    return true;
            }
            return false;
        }
        public int GetIndexOfHero(string name)
        {
            for (int i = 0; i < _heroes.Count; i++)
            {
                if (_heroes[i].Trim().ToUpper() == name.Trim().ToUpper())
                    return i;
            }
            return -1;
        }
        public bool AddHero(string name)
        {
            if (!IsExistHero(name))
            {
                _heroes.Add(name);
                return true;
            }
            return false;
        }
        public bool ChangeHero(string oldname, string newname)
        {
            if (!IsExistHero(newname) && IsExistHero(oldname))
            {
                _heroes[GetIndexOfHero(oldname)] = newname;
                return true;
            }
            return false;
        }
        public bool DelHero(string name)
        {
            if (IsExistHero(name))
            {
                _heroes.RemoveAt(GetIndexOfHero(name));
                return true;
            }
            return false;
        }
    }
    [Serializable]
    public class Taxonomia
    {
        private List<Role> _lstRoles; 
        public List<Role> Roles
        {
            set { _lstRoles = value; }
            get { return _lstRoles; }
        }
        public Taxonomia()
        {
            _lstRoles=new List<Role>();
        }
        public bool IsExistRole(string name)
        {
            foreach (Role r in _lstRoles)
            {
                if (r.Name.Trim().ToUpper() == name.Trim().ToUpper())
                    return true;
            }
            return false;
        }
        public Role GetRole(string name)
        {
            foreach (Role r in _lstRoles)
            {
                if (r.Name.Trim().ToUpper() == name.Trim().ToUpper())
                    return r;
            }
            return null;
        }
        public bool AddRole(string name)
        {
            if (!IsExistRole(name))
            {
                _lstRoles.Add(new Role(name));
                return true;
            }
            return false;
        }
        public bool ChangeRole(string oldname, string newname)
        {
            if (!IsExistRole(newname) && IsExistRole(oldname))
            {
                GetRole(oldname).Name = newname;
                return true;
            }
            return false;
        }
        public bool DelRole(string name)
        {
            if (IsExistRole(name))
            {
                _lstRoles.Remove(GetRole(name));
                return true;
            }
            return false;
        }

    }

    [Serializable]
    public class ClassSemanticNet
    {
        public List<ClassNode> LstNodes
        { set; get; }

        //Саша-списки всего,для удобства
        public List<String> LstAgents
        { set; get; }
        public List<String> LstActions
        { set; get; }
        public List<String> LstRecipients
        { set; get; }
        public List<String> LstObjs
        { set; get; }
        public List<String> LstLocotivs
        { set; get; }
        public List<String> LstTimes
        { set; get; }
        public Taxonomia Taxon
       { set; get; }

          
        public bool isSaved=true;
        //------------имя файла для сохранения------------------------------------------------------------
        public string fileName="";
        public string FileName
        {
            set { fileName = value; }
            get { return fileName; }
        }
        public bool IsSaved
        {
            set { isSaved = value; }
            get { return isSaved; }
        }
        //============имя файла для сохранения=============================================================
        
        //------------Очистка структуры--------------------------------------------------------------------
        public void Clear()
        {
            LstNodes.Clear();
            isSaved = false;
            fileName = "";
        }
        //============Очистка структуры====================================================================

        /*//------------Получение ссылки на сцену по имени---------------------------------------------------
        public ClassNode GetSceneByName(string NameOsScene)
        {
            foreach (ClassNode node in LstNodes)
                if (node.TypeN==TypeNode.Scene)
                    if (node.Name.Trim().ToUpper() == NameOsScene.Trim().ToUpper())
                        return node;
            return null;
        }
        //============Получение ссылки на сцену по имени===================================================*/

        public ClassSemanticNet()
        {
            LstNodes = new List<ClassNode>();
            LstAgents = new List<String>();
            LstRecipients = new List<String>();
            LstObjs=new List<string>();
            LstLocotivs=new List<string>();
            LstTimes = new List<string>();
            LstActions = new List<string>();
            Taxon = new Taxonomia();
        }

        public bool AddScene(string name)
        {
            LstNodes.Add(new ClassNode(TypeNode.Scene));
            LstNodes[LstNodes.Count - 1].Name = name;
            return true;
        }
        //Саша-изменение сцены
        public bool ChScene(ClassNode sc, string name)
        {
            sc.Name = name;
            return true;
        }

        public bool AddAction(string Agent, string Recipient, string ToDo, string Locot, string Time, string Obj, float X, float Y)
        {
            //Саша-проверка есть ли уже такая рамка падежная!!!
            bool ag = false, rec = false, loco = false, tim = false, objec = false,act=false;
            ClassCase agg = null, locc = null, recip = null, ob = null, tt = null,actToDo=null;
            foreach (ClassNode item in LstNodes)
            {
                if (item.TypeN == TypeNode.Action)
                {
                    if (item.CaseFrame.Agent.Name == Agent)
                    {
                        ag = true;
                        agg = item.CaseFrame.Agent;
                    }
                    if (item.CaseFrame.Recipient.Name == Agent)
                    {
                        ag = true;
                        agg = item.CaseFrame.Recipient;
                    }
                    if (item.CaseFrame.Agent.Name == Recipient)
                    {
                        rec = true;
                        recip = item.CaseFrame.Agent;
                    }
                    if (item.CaseFrame.Recipient.Name == Recipient)
                    {
                        rec = true;
                        recip = item.CaseFrame.Recipient;
                    }
                    if (item.CaseFrame.Time.Name == Time)
                    {
                        tim = true;
                        tt = item.CaseFrame.Time;
                    }
                    if (item.CaseFrame.Obj.Name == Obj)
                    {
                        objec = true;
                        ob = item.CaseFrame.Obj;
                    }
                    if (item.CaseFrame.Lokotiv.Name == Locot)
                    {
                        loco = true;
                        locc = item.CaseFrame.Lokotiv;
                    }
                    if (item.CaseFrame.ToDo.Name == ToDo)
                    {
                        act = true;
                        actToDo = item.CaseFrame.ToDo;
                    }
                }
            }
            LstNodes.Add(new ClassNode(TypeNode.Action));
            LstNodes[LstNodes.Count - 1].CaseFrame = new ClassCaseFrame();
            if (!ag)
            {
                LstNodes[LstNodes.Count - 1].CaseFrame.Agent = new ClassCase();
                LstNodes[LstNodes.Count - 1].CaseFrame.Agent.Name = Agent;
            }
            else
                LstNodes[LstNodes.Count - 1].CaseFrame.Agent = agg;
            if (!act)
            {
                LstNodes[LstNodes.Count - 1].CaseFrame.ToDo = new ClassCase();
                LstNodes[LstNodes.Count - 1].CaseFrame.ToDo.Name = ToDo;
            }
            else
                LstNodes[LstNodes.Count - 1].CaseFrame.ToDo = actToDo;
            if (!loco)
            {
                LstNodes[LstNodes.Count - 1].CaseFrame.Lokotiv = new ClassCase();
                LstNodes[LstNodes.Count - 1].CaseFrame.Lokotiv.Name = Locot;
            }
            else
                LstNodes[LstNodes.Count - 1].CaseFrame.Lokotiv = locc;

            LstNodes[LstNodes.Count - 1].CaseFrame.ToDo = new ClassCase();
            LstNodes[LstNodes.Count - 1].CaseFrame.ToDo.Name = ToDo;
            if (!tim)
            {
                LstNodes[LstNodes.Count - 1].CaseFrame.Time = new ClassCase();
                LstNodes[LstNodes.Count - 1].CaseFrame.Time.Name = Time;
            }
            else
                LstNodes[LstNodes.Count - 1].CaseFrame.Time = tt;
            if (!rec)
            {
                LstNodes[LstNodes.Count - 1].CaseFrame.Recipient = new ClassCase();
                LstNodes[LstNodes.Count - 1].CaseFrame.Recipient.Name = Recipient;
            }
            else
                LstNodes[LstNodes.Count - 1].CaseFrame.Recipient = recip;
            if (!objec)
            {
                LstNodes[LstNodes.Count - 1].CaseFrame.Obj = new ClassCase();
                LstNodes[LstNodes.Count - 1].CaseFrame.Obj.Name = Obj;
            }
            else
                LstNodes[LstNodes.Count - 1].CaseFrame.Obj = ob;
            //конец Саша-30.03.11
            //start Ирина (22.03.11)
            LstNodes[LstNodes.Count - 1].CaseFrame.Agent.X_d2 = X - 30;
            LstNodes[LstNodes.Count - 1].CaseFrame.Agent.Y_d2 = Y;
            LstNodes[LstNodes.Count - 1].CaseFrame.Recipient.X_d2 = X - 30;
            LstNodes[LstNodes.Count - 1].CaseFrame.Recipient.Y_d2 = Y - 5;
            LstNodes[LstNodes.Count - 1].CaseFrame.ToDo.X_d2 = X - 30;
            LstNodes[LstNodes.Count - 1].CaseFrame.ToDo.Y_d2 = Y - 10;
            LstNodes[LstNodes.Count - 1].CaseFrame.Lokotiv.X_d2 = X + 30;
            LstNodes[LstNodes.Count - 1].CaseFrame.Lokotiv.Y_d2 = Y;
            LstNodes[LstNodes.Count - 1].CaseFrame.Obj.X_d2 = X + 30;
            LstNodes[LstNodes.Count - 1].CaseFrame.Obj.Y_d2 = Y - 5;
            LstNodes[LstNodes.Count - 1].CaseFrame.Time.X_d2 = X + 30;
            LstNodes[LstNodes.Count - 1].CaseFrame.Time.Y_d2 = Y - 10;
            //end Ирина (22.03.11)
            //Саша-добавление значений, если таких ещё не было
            if (ToDo != "")
            {
                if (!LstActions.Contains(ToDo))
                    LstActions.Add(ToDo);
            }
            if (Recipient != "")
            {
                if (!LstRecipients.Contains(Recipient))
                    LstRecipients.Add(Recipient);
            }
            if (Agent != "")
            {
                if (!LstAgents.Contains(Agent))
                    LstAgents.Add(Agent);
            }
            if (Locot != "")
            {
                if (!LstLocotivs.Contains(Locot))
                    LstLocotivs.Add(Locot);
            }
            if (Time != "")
            {
                if (!LstTimes.Contains(Time))
                    LstTimes.Add(Time);
            }
            if (Obj != "")
            {
                if (!LstObjs.Contains(Obj))
                    LstObjs.Add(Obj);
            }
            return true;
        }

        //Саша-изменение действия
        public bool ChAction(ClassNode ac, string Agent, string Recipient, string ToDo, string Locot, string Time, string Obj)
        {
            //Саша-проверка есть ли уже такая рамка падежная!!!
            bool ag = false, rec = false, loco = false, tim = false, objec = false,act=false;
            ClassCase agg = null, locc = null, recip = null, ob = null, tt = null,actToDo=null;
            foreach (ClassNode item in LstNodes)
            {
                if (item.TypeN == TypeNode.Action && item != ac)
                {
                    if (item.CaseFrame.Agent.Name == Agent)
                    {
                        ag = true;
                        agg = item.CaseFrame.Agent;
                    }
                    if (item.CaseFrame.ToDo.Name == ToDo)
                    {
                        act = true;
                        actToDo = item.CaseFrame.ToDo;
                    }
                    if (item.CaseFrame.Recipient.Name == Recipient)
                    {
                        rec = true;
                        recip = item.CaseFrame.Recipient;
                    }
                    if (item.CaseFrame.Time.Name == Time)
                    {
                        tim = true;
                        tt = item.CaseFrame.Time;
                    }
                    if (item.CaseFrame.Obj.Name == Obj)
                    {
                        objec = true;
                        ob = item.CaseFrame.Obj;
                    }
                    if (item.CaseFrame.Lokotiv.Name == Locot)
                    {
                        loco = true;
                        locc = item.CaseFrame.Lokotiv;
                    }
                }
            }
            if (ac.CaseFrame.Agent == null)
            {
                ac.CaseFrame.Agent = new ClassCase();
                ac.CaseFrame.Lokotiv = new ClassCase();
                ac.CaseFrame.Obj = new ClassCase();
                ac.CaseFrame.Recipient = new ClassCase();
                ac.CaseFrame.Time = new ClassCase();
                ac.CaseFrame.ToDo = new ClassCase();
            }
            if (!ag)
            {
                ac.CaseFrame.Agent.Name = Agent;
            }
            else
                ac.CaseFrame.Agent = agg;
            if (!loco)
                ac.CaseFrame.Lokotiv.Name = Locot;
            else
                ac.CaseFrame.Lokotiv = locc;

            if (!act)
                ac.CaseFrame.ToDo.Name = ToDo;
            else
                ac.CaseFrame.ToDo = actToDo;

            if (!tim)
                ac.CaseFrame.Time.Name = Time;
            else
                ac.CaseFrame.Time = tt;
            if (!rec)
                ac.CaseFrame.Recipient.Name = Recipient;
            else
                ac.CaseFrame.Recipient = recip;
            if (!objec)
                ac.CaseFrame.Obj.Name = Obj;
            else
                ac.CaseFrame.Obj = ob;
            //конец Саша-30.03.11
            if (ToDo != "")
            {
                if (!LstActions.Contains(ToDo))
                    LstActions.Add(ToDo);
            }
            if (Recipient != "")
            {
                if (!LstRecipients.Contains(Recipient))
                    LstRecipients.Add(Recipient);
            }
            if (Agent != "")
            {
                if (!LstAgents.Contains(Agent))
                    LstAgents.Add(Agent);
            }
            if (Locot != "")
            {
                if (!LstLocotivs.Contains(Locot))
                    LstLocotivs.Add(Locot);
            }
            if (Time != "")
            {
                if (!LstTimes.Contains(Time))
                    LstTimes.Add(Time);
            }
            if (Obj != "")
            {
                if (!LstObjs.Contains(Obj))
                    LstObjs.Add(Obj);
            }
            return true;
        }

        public bool DelNode()
        {
            return true;
        }

    }
   

}
